package com.shlh.saas.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.shlh.saas.common.UserContext;
import com.shlh.saas.entity.EmailSendRecord;
import com.shlh.saas.entity.UserBalance;
import com.shlh.saas.entity.UserEmail;
import com.shlh.saas.mapper.EmailSendRecordMapper;
import com.shlh.saas.model.dto.BulkSendRequest;
import com.shlh.saas.model.dto.CustomEmailSendDTO;
import com.shlh.saas.service.CustomEmailService;
import com.shlh.saas.service.EmailService;
import com.shlh.saas.service.OutlookOAuthService;
import com.shlh.saas.service.UserBalanceService;
import com.shlh.saas.util.RedisUtils;
import com.tencentcloudapi.ess.v20201111.models.Recipient;
import jakarta.activation.DataHandler;
import jakarta.mail.*;
import jakarta.mail.internet.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 自定义邮件服务实现类
 */
@Service
public class CustomEmailServiceImpl implements CustomEmailService {

    private static final Logger log = LoggerFactory.getLogger(CustomEmailServiceImpl.class);

    // 定义常用邮箱的域名正则表达式
    private static final Pattern QQ_EMAIL = Pattern.compile("^[a-zA-Z0-9_-]+@qq\\.com$");
    private static final Pattern EMAIL_163 = Pattern.compile("^[a-zA-Z0-9_-]+@163\\.com$");
    private static final Pattern EMAIL_126 = Pattern.compile("^[a-zA-Z0-9_-]+@126\\.com$");
    private static final Pattern EMAIL_SINA = Pattern.compile("^[a-zA-Z0-9_-]+@(sina\\.com|sina\\.cn)$");
    private static final Pattern EMAIL_GMAIL = Pattern.compile("^[a-zA-Z0-9_-]+@gmail\\.com$");
    private static final Pattern EMAIL_OUTLOOK = Pattern.compile("^[a-zA-Z0-9_-]+@(outlook\\.com|hotmail\\.com)$");
    private static final Pattern EMAIL_YAHOO = Pattern.compile("^[a-zA-Z0-9_-]+@yahoo\\.com$");

    private static final String QQ_EMAIL_ = "qq";
    private static final String EMAIL_163_ = "163";
    private static final String EMAIL_126_ = "126";
    private static final String EMAIL_SINA_ = "sina";
    private static final String EMAIL_GMAIL_ = "gmail";
    private static final String EMAIL_OUTLOOK_ = "outlook";
    private static final String EMAIL_YAHOO_ = "yahoo";
    @Autowired
    private EmailSendRecordMapper emailSendRecordMapper;

    @Autowired
    private EmailService emailService;

    @Autowired
    private OutlookOAuthService outlookOAuthService;

    @Autowired
    private UserBalanceService userBalanceService;

    @Value("${spring.mail.proxy.enabled:false}")
    private boolean proxyEnabled;

    @Value("${spring.mail.proxy.host:127.0.0.1}")
    private String proxyHost;

    @Value("${spring.mail.proxy.port:7890}")
    private String proxyPort;

    @Value("${spring.mail.proxy.socks.host:127.0.0.1}")
    private String socksProxyHost;

    @Value("${spring.mail.proxy.socks.port:7890}")
    private String socksProxyPort;

    @Value("${spring.mail.proxy.timeout:10000}")
    private String proxyTimeout;

    @Value("${spring.mail.proxy.debug:false}")
    private boolean mailDebug;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sendCustomHtmlEmail(CustomEmailSendDTO customEmailSendDTO) {
        try {

            String senderEmail = customEmailSendDTO.getSenderEmail();
            String recipients = customEmailSendDTO.getRecipients();
            UserEmail userEmail = emailService.getUserEmailByUserIdAndEmail(customEmailSendDTO.getUserId(), senderEmail);

            String authCode = userEmail.getEmailPassword();
            String emailProvider = userEmail.getEmailProvider();

            customEmailSendDTO.setSenderAuthCode(authCode);

            // 获取邮箱配置
            EmailServerConfig config = getEmailServerConfig(emailProvider);
            if (config == null) {
                log.error("不支持的邮箱类型: {}", senderEmail);
                return false;
            }

            // 处理收件人
            List<String> recipientList = parseRecipients(recipients);
            if (recipientList.isEmpty()) {
                log.error("收件人列表为空");
                return false;
            }

//             尝试使用主要配置发送
            try {
                if (emailProvider.equals("outlook")) {
                    return sendEmailByOutlook(userEmail.getId(), recipientList, customEmailSendDTO.getSubject(), customEmailSendDTO.getContent(), customEmailSendDTO.getSendEmailId());
                } else {
                    return sendEmailWithConfig(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config);
                }
            } catch (Exception e) {
                log.warn("使用主要配置发送邮件失败: {}，尝试备用配置...", e.getMessage());

                // 如果是QQ邮箱，尝试其他端口和配置
                if (QQ_EMAIL.matcher(senderEmail).matches()) {
                    // 尝试端口587 + STARTTLS
                    try {
                        EmailServerConfig config587 = new EmailServerConfig("smtp.qq.com", 587, true);
                        return sendEmailWithConfig(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config587);
                    } catch (Exception e2) {
                        log.warn("使用QQ邮箱端口587失败: {}", e2.getMessage());

                        // 尝试端口25
                        try {
                            EmailServerConfig config25 = new EmailServerConfig("smtp.qq.com", 25, true);
                            return sendEmailWithConfig(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config25);
                        } catch (Exception e3) {
                            log.warn("使用QQ邮箱端口25失败: {}", e3.getMessage());

                            // 尝试直接IP地址
                            try {
                                // 使用QQ邮箱IP地址 (可能需要更新为最新IP)
                                EmailServerConfig configIP = new EmailServerConfig("183.3.225.43", 465, false);
                                return sendEmailWithConfig(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, configIP);
                            } catch (Exception e4) {
                                log.error("所有QQ邮箱配置都失败: {}", e4.getMessage());
                                throw e4; // 重新抛出最后一个异常
                            }
                        }
                    }
                }
                // 如果是新浪邮箱，尝试其他端口和配置
                else if (EMAIL_SINA.matcher(senderEmail).matches()) {
                    // 尝试端口587 + STARTTLS
                    try {
                        EmailServerConfig config587 = new EmailServerConfig("smtp.sina.com", 587, true);
                        return sendEmailWithConfig(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config587);
                    } catch (Exception e2) {
                        log.warn("使用新浪邮箱端口587失败: {}", e2.getMessage());

                        // 尝试端口994 + SSL
                        try {
                            EmailServerConfig config994 = new EmailServerConfig("smtp.sina.com", 994, false);
                            return sendEmailWithConfig(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config994);
                        } catch (Exception e3) {
                            log.error("所有新浪邮箱配置都失败: {}", e3.getMessage());
                            throw e3; // 重新抛出最后一个异常
                        }
                    }
                } else {
                    // 其他邮箱类型直接重新抛出异常
                    throw e;
                }
            }
        } catch (Exception e) {
            log.error("保存自定义HTML邮件失败: {}", e.getMessage(), e);
            return false;
        }
    }

    private boolean sendEmailByOutlook(Long id, List<String> recipientList, String subject, String content, Long sendEmailId) {

        UserEmail config = emailService.findById(id);
        int success = 0;

        Set<String> targetEmails = new HashSet<>(recipientList);
        List<String> emails = new ArrayList<>(targetEmails);
        for (String to : emails) {
            try {
//                boolean ok = outlookOAuthService.sendMailViaGraph(config.getAccessToken(), config.getEmail(), subject, content, to);
                boolean ok = outlookOAuthService.sendEmailInfo(config.getEmail(), config.getClientId(), config.getClientSecret(), config.getTenantId(), subject, content, to);
                if (ok) {
                    success++;
                } else {
                    // 发送失败记录
                    emailSendRecordMapper.failEmailSend(sendEmailId);
                    log.info("发送失败，邮箱记录id为：{}", sendEmailId);
                    return false;
                }
            } catch (Exception ex) {
                // 添加错误记录
                log.info("Graph发送失败: {}" + ex.getMessage());
            }
        }

        // 发送成功记录
        emailSendRecordMapper.successEmailSend(sendEmailId, success);

        return success > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sendCustomAttachmentEmail(CustomEmailSendDTO customEmailSendDTO, List<MultipartFile> attachments) {
        try {
            String senderEmail = customEmailSendDTO.getSenderEmail();
            String recipients = customEmailSendDTO.getRecipients();

            UserEmail userEmail = emailService.getUserEmailByUserIdAndEmail(customEmailSendDTO.getUserId(), senderEmail);
            String authCode = userEmail.getEmailPassword();
            customEmailSendDTO.setSenderAuthCode(authCode);

            String emailProvider = userEmail.getEmailProvider();
            // 获取邮箱配置
            EmailServerConfig config = getEmailServerConfig(emailProvider);
            if (config == null) {
                log.error("不支持的邮箱类型: {}", senderEmail);
                return false;
            }

            // 处理收件人
            List<String> recipientList = parseRecipients(recipients);
            if (recipientList.isEmpty()) {
                log.error("收件人列表为空");
                return false;
            }

            // 处理附件
            if (attachments == null || attachments.isEmpty()) {
                // 如果没有附件，调用HTML邮件发送方法
                return sendCustomHtmlEmail(customEmailSendDTO);
            }

            // 尝试使用主要配置发送
            try {
                if (userEmail.getEmailProvider().equals("outlook")) {

                    return sendEmailWithAttachmentsByOutlook(userEmail.getId(), recipientList, customEmailSendDTO.getSubject(), customEmailSendDTO.getContent(), attachments, customEmailSendDTO.getSendEmailId());

                } else {
                    // 准备附件数据
                    List<AttachmentData> attachmentDataList = new ArrayList<>();
                    for (MultipartFile file : attachments) {
                        if (file != null && !file.isEmpty()) {
                            try {
                                String filename = file.getOriginalFilename();
                                byte[] fileData = file.getBytes();
                                attachmentDataList.add(new AttachmentData(filename, fileData));
                            } catch (IOException e) {
                                log.error("读取附件数据失败: {}", e.getMessage(), e);
                                return false;
                            }
                        }
                    }

                    return sendEmailWithAttachments(userEmail.getId(), customEmailSendDTO, recipientList, config, attachmentDataList);
                }
            } catch (Exception e) {
                log.warn("使用主要配置发送带附件邮件失败: {}，尝试备用配置...", e.getMessage());

                List<AttachmentData> attachmentDataList = new ArrayList<>();
                for (MultipartFile file : attachments) {
                    if (file != null && !file.isEmpty()) {
                        try {
                            String filename = file.getOriginalFilename();
                            byte[] fileData = file.getBytes();
                            attachmentDataList.add(new AttachmentData(filename, fileData));
                        } catch (IOException eq) {
                            log.error("读取附件数据失败: {}", e.getMessage(), eq);
                            return false;
                        }
                    }
                }

                // 如果是QQ邮箱，尝试其他端口和配置
                if (QQ_EMAIL.matcher(senderEmail).matches()) {
                    // 尝试端口587 + STARTTLS
                    try {
                        EmailServerConfig config587 = new EmailServerConfig("smtp.qq.com", 587, true);
                        return sendEmailWithAttachments(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config587, attachmentDataList);
                    } catch (Exception e2) {
                        log.warn("使用QQ邮箱端口587发送带附件邮件失败: {}", e2.getMessage());

                        // 尝试端口25
                        try {
                            EmailServerConfig config25 = new EmailServerConfig("smtp.qq.com", 25, true);
                            return sendEmailWithAttachments(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config25, attachmentDataList);
                        } catch (Exception e3) {
                            log.error("所有QQ邮箱配置发送带附件邮件都失败: {}", e3.getMessage());
                            throw e3; // 重新抛出最后一个异常
                        }
                    }
                }
                // 如果是新浪邮箱，尝试其他端口和配置
                else if (EMAIL_SINA.matcher(senderEmail).matches()) {
                    // 尝试端口587 + STARTTLS
                    try {
                        EmailServerConfig config587 = new EmailServerConfig("smtp.sina.com", 587, true);
                        return sendEmailWithAttachments(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config587, attachmentDataList);
                    } catch (Exception e2) {
                        log.warn("使用新浪邮箱端口587发送带附件邮件失败: {}", e2.getMessage());

                        // 尝试端口994 + SSL
                        try {
                            EmailServerConfig config994 = new EmailServerConfig("smtp.sina.com", 994, false);
                            return sendEmailWithAttachments(customEmailSendDTO.getSendEmailId(), customEmailSendDTO, recipientList, config994, attachmentDataList);
                        } catch (Exception e3) {
                            log.error("所有新浪邮箱配置发送带附件邮件都失败: {}", e3.getMessage());
                            throw e3; // 重新抛出最后一个异常
                        }
                    }
                } else {
                    // 其他邮箱类型直接重新抛出异常
                    throw e;
                }
            }
        } catch (Exception e) {
            log.error("发送自定义带附件邮件失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Transactional(rollbackFor = Exception.class)
    private boolean sendEmailWithAttachmentsByOutlook(Long id, List<String> recipientList, String subject, String content, List<MultipartFile> attachments, Long sendEmailId) {
        UserEmail config = emailService.findById(id);
        int success = 0;

        Set<String> targetEmails = new HashSet<>(recipientList);
        List<String> emails = new ArrayList<>(targetEmails);

        List<Map<String, Object>> graphAttachments = buildGraphAttachments(attachments);

        for (String to : emails) {
            try {
                boolean ok = outlookOAuthService.sendEmailInfoWithAttachments(config.getEmail(), config.getClientId(), config.getClientSecret(), config.getTenantId(), subject, content, to, graphAttachments);
                if (ok) {
                    success++;
                } else {
                    // 修改失败记录
                    emailSendRecordMapper.failEmailSend(sendEmailId);
                    return false;
                }
                //修改成功记录
                emailSendRecordMapper.successEmailSend(sendEmailId, success);

            } catch (Exception ex) {
                emailSendRecordMapper.failEmailSend(sendEmailId);
                // 添加错误记录
                System.err.println("Graph发送失败: " + ex.getMessage());
            }
        }

        return success > 0;
    }

    private boolean sendOutlookEmailWithAttachments(Long id, List<String> recipientList, String subject, String content, List<MultipartFile> attachmentDataList) {
        UserEmail config = emailService.findById(id);
        int success = 0;

        Set<String> targetEmails = new HashSet<>(recipientList);
        List<String> emails = new ArrayList<>(targetEmails);

        List<Map<String, Object>> graphAttachments = buildGraphAttachments(attachmentDataList);

        for (String to : emails) {
            try {

                boolean ok = outlookOAuthService.sendMailViaGraph(config.getAccessToken(), config.getEmail(), subject, content, to, graphAttachments);
                if (ok) {
                    success++;
                } else {
                    // 添加错误记录

                }
            } catch (Exception ex) {
//                failedAddresses.add(to);
                // 添加错误记录
                System.err.println("Graph发送失败: " + ex.getMessage());
            }
        }

        return success > 0;
    }

    private List<Map<String, Object>> buildGraphAttachments(List<MultipartFile> attachments) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
//            if (images != null) {
//                for (MultipartFile f : images) {
//                    if (f != null && !f.isEmpty()) {
//                        Map<String, Object> m = new HashMap<>();
//                        m.put("@odata.type", "#microsoft.graph.fileAttachment");
//                        m.put("name", f.getOriginalFilename());
//                        m.put("contentType", f.getContentType());
//                        m.put("contentBytes", Base64.getEncoder().encodeToString(f.getBytes()));
//                        list.add(m);
//                    }
//                }
//            }
            if (attachments != null) {
                for (MultipartFile f : attachments) {
                    if (f != null && !f.isEmpty()) {
                        Map<String, Object> m = new HashMap<>();
                        m.put("@odata.type", "#microsoft.graph.fileAttachment");
                        m.put("name", f.getOriginalFilename());
                        m.put("contentType", f.getContentType());
                        m.put("contentBytes", Base64.getEncoder().encodeToString(f.getBytes()));
                        list.add(m);
                    }
                }
            }
        } catch (IOException e) {
            System.err.println("构建Graph附件失败: " + e.getMessage());
        }
        return list;
    }


    /**
     * 创建邮件会话
     *
     * @param config      邮箱服务器配置
     * @param senderEmail 发件人邮箱
     * @param authCode    授权码
     * @return 邮件会话
     */
    private Session createMailSession(EmailServerConfig config, String senderEmail, String authCode) {
        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", config.getHost());
        props.put("mail.smtp.port", String.valueOf(config.getPort()));
        props.put("mail.smtp.timeout", proxyTimeout);
        props.put("mail.smtp.connectiontimeout", proxyTimeout);

        // 根据服务器配置添加安全设置
        if (config.isStartTlsEnable()) {
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.ssl.protocols", "TLSv1.2");
        } else {
            // 对于使用SSL的服务器（如QQ邮箱的465端口）
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.socketFactory.port", String.valueOf(config.getPort()));
            props.put("mail.smtp.ssl.enable", "true");
        }

        // 为Gmail邮箱添加特殊配置
        if (config.getHost().equals("smtp.gmail.com")) {
            props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
        }

        // 完全禁用代理设置
        props.remove("mail.smtp.socks.host");
        props.remove("mail.smtp.proxy.host");
        props.remove("mail.smtp.socks.port");
        props.remove("mail.smtp.proxy.port");

        // 禁用系统代理
        props.put("mail.smtp.usesocksproxy", "false");
        props.put("mail.smtp.useproxy", "false");

        // 启用调试
        props.put("mail.debug", "true");

        // 创建带认证的会话
        final String username = senderEmail;
        final String password = authCode;

        // 创建Authenticator对象，确保用户名和密码正确传递
        Authenticator auth = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        };

        // 使用显式传递用户名和密码的方式创建会话
        Session session = Session.getInstance(props, auth);

        // 记录认证信息用于调试
        log.info("创建邮件会话，用户名: {}, 授权码长度: {}, 服务器: {}:{}",
                username, (password != null ? password.length() : 0), config.getHost(), config.getPort());

        return session;
    }

    /**
     * 根据邮箱地址获取对应的邮箱服务器配置
     *
     * @param email 邮箱地址
     * @return 邮箱服务器配置
     */
    private EmailServerConfig getEmailServerConfig(String email) {
        if (email == null || email.isEmpty()) {
            return null;
        }

        // QQ邮箱
        if (QQ_EMAIL_.equals(email)) {
            return new EmailServerConfig("smtp.qq.com", 465, false); // 使用SSL端口465
        }
        // 163邮箱
        else if (EMAIL_163_.equals(email)) {
            return new EmailServerConfig("smtp.163.com", 25, true);
        }
        // 126邮箱
        else if (EMAIL_126_.equals(email)) {
            return new EmailServerConfig("smtp.126.com", 25, true);
        }
        // 新浪邮箱
        else if (EMAIL_SINA_.equals(email)) {
            return new EmailServerConfig("smtp.sina.com", 465, false); // 修改为端口465，使用SSL
        }
        // Gmail邮箱
        else if (EMAIL_GMAIL_.equals(email)) {
            return new EmailServerConfig("smtp.gmail.com", 587, true);
        }
        // Outlook/Hotmail邮箱
        else if (EMAIL_OUTLOOK_.equals(email)) {
            return new EmailServerConfig("smtp.office365.com", 587, true);
        }
        // Yahoo邮箱
        else if (EMAIL_YAHOO_.equals(email)) {
            return new EmailServerConfig("smtp.mail.yahoo.com", 587, true);
        }

        return null; // 未识别的邮箱类型
    }

    /**
     * 解析收件人列表
     *
     * @param recipients 收件人字符串（多个用分号分隔）
     * @return 收件人列表
     */
    private List<String> parseRecipients(String recipients) {
        if (!StringUtils.hasText(recipients)) {
            return new ArrayList<>();
        }

        return Arrays.stream(recipients.split(";"))
                .map(String::trim)
                .filter(StringUtils::hasText)
                .collect(Collectors.toList());
    }

    /**
     * 使用指定配置发送邮件
     */
    private boolean sendEmailWithConfig(Long id, CustomEmailSendDTO customEmailSendDTO, List<String> recipientList, EmailServerConfig config) throws MessagingException {
        String senderEmail = customEmailSendDTO.getSenderEmail();
        String authCode = customEmailSendDTO.getSenderAuthCode();

        if (authCode == null || authCode.isEmpty()) {
            log.error("授权码为空，无法发送邮件");
            return false;
        }

        int successCount = 0;
        int failureCount = 0;
        Transport transport = null;

        try {
            // 创建邮件会话 (在循环外创建一次)
            Session session = createMailSession(config, senderEmail, authCode);

            // 获取Transport对象并连接到服务器 (在循环外连接一次)
            transport = session.getTransport("smtp");
            log.info("正在连接到SMTP服务器: {}:{}", config.getHost(), config.getPort());
            transport.connect(config.getHost(), config.getPort(), senderEmail, authCode);

            // 解析抄送和密送列表 (在循环外解析一次)
            List<String> ccList = new ArrayList<>();
            if (StringUtils.hasText(customEmailSendDTO.getCc())) {
                ccList = parseRecipients(customEmailSendDTO.getCc());
            }

            List<String> bccList = new ArrayList<>();
            if (StringUtils.hasText(customEmailSendDTO.getBcc())) {
                bccList = parseRecipients(customEmailSendDTO.getBcc());
            }

            // 遍历收件人列表，为每个收件人发送单独邮件
            for (String recipient : recipientList) {
                try {
                    // 为每个收件人创建新的邮件消息
                    MimeMessage message = new MimeMessage(session);
                    MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

                    // 设置发件人
                    helper.setFrom(senderEmail);
                    // 设置主要收件人 (当前循环的收件人)
                    helper.setTo(recipient);
                    // 设置邮件主题
                    helper.setSubject(customEmailSendDTO.getSubject());
                    // 设置邮件内容 (HTML格式)
                    helper.setText(customEmailSendDTO.getContent(), true);

                    // 设置抄送人
                    if (!ccList.isEmpty()) {
                        helper.setCc(ccList.toArray(new String[0]));
                    }

                    // 设置密送人
                    if (!bccList.isEmpty()) {
                        helper.setBcc(bccList.toArray(new String[0]));
                    }

                    // 发送邮件 (使用已建立的连接)
                    transport.sendMessage(message, message.getAllRecipients());

                    log.info("邮件成功发送至: {}", recipient);
                    successCount++;

                    // 添加短暂延迟，避免发送频率过高触发服务器限制
                    Thread.sleep(100); // 可根据需要取消注释

                } catch (Exception e) {
                    log.error("发送邮件到 {} 时失败: {}", recipient, e.getMessage());
                    failureCount++;
                }
            }

            log.info("邮件发送完成: 成功 {} 封, 失败 {} 封", successCount, failureCount);

        } catch (Exception e) {
            log.error("邮件发送过程中发生异常: {}", e.getMessage());
            return false;
        } finally {
            // 确保关闭连接
            if (transport != null && transport.isConnected()) {
                try {
                    transport.close();
                    log.info("SMTP连接已关闭");
                } catch (Exception e) {
                    log.warn("关闭SMTP连接时出错: {}", e.getMessage());
                }
            }

            // 更新发送记录
            try {
                emailSendRecordMapper.successEmailSend(id, successCount);
            } catch (Exception e) {
                log.warn("更新邮件发送记录时出错: {}", e.getMessage());
            }
        }

        return true;
    }

    /**
     * 使用指定配置发送带附件的邮件
     */
    @Transactional(rollbackFor = Exception.class)
    private boolean sendEmailWithAttachments(Long id, CustomEmailSendDTO customEmailSendDTO, List<String> recipientList,
                                             EmailServerConfig config, List<AttachmentData> attachments) throws MessagingException {
        String senderEmail = customEmailSendDTO.getSenderEmail();
        String authCode = customEmailSendDTO.getSenderAuthCode();

        if (authCode == null || authCode.isEmpty()) {
            log.error("授权码为空，无法发送邮件");
            return false;
        }

        int successCount = 0;
        int failureCount = 0;
        Transport transport = null;

        try {
            // 创建邮件会话 (在循环外创建一次)
            Session session = createMailSession(config, senderEmail, authCode);

            // 获取Transport对象并连接到服务器 (在循环外连接一次)
            transport = session.getTransport("smtp");
            log.info("正在连接到SMTP服务器: {}:{}", config.getHost(), config.getPort());
            transport.connect(config.getHost(), config.getPort(), senderEmail, authCode);

            // 解析抄送和密送列表 (在循环外解析一次)
            List<String> ccList = new ArrayList<>();
            if (StringUtils.hasText(customEmailSendDTO.getCc())) {
                ccList = parseRecipients(customEmailSendDTO.getCc());
            }

            List<String> bccList = new ArrayList<>();
            if (StringUtils.hasText(customEmailSendDTO.getBcc())) {
                bccList = parseRecipients(customEmailSendDTO.getBcc());
            }

            // 遍历收件人列表，为每个收件人发送单独邮件
            for (String recipient : recipientList) {
                try {
                    // 为每个收件人创建新的邮件消息
                    MimeMessage message = new MimeMessage(session);
                    MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

                    // 设置发件人
                    helper.setFrom(senderEmail);
                    // 设置主要收件人 (当前循环的收件人)
                    helper.setTo(recipient);
                    // 设置邮件主题
                    helper.setSubject(customEmailSendDTO.getSubject());
                    // 设置邮件内容 (HTML格式)
                    helper.setText(customEmailSendDTO.getContent(), true);

                    // 设置抄送人
                    if (!ccList.isEmpty()) {
                        helper.setCc(ccList.toArray(new String[0]));
                    }

                    // 设置密送人
                    if (!bccList.isEmpty()) {
                        helper.setBcc(bccList.toArray(new String[0]));
                    }

                    // 添加附件 (为每封邮件添加所有附件)[2,5,7](@ref)
                    for (AttachmentData attachment : attachments) {
                        helper.addAttachment(attachment.getFilename(), new ByteArrayResource(attachment.getData()));
                    }

                    // 发送邮件 (使用已建立的连接)
                    transport.sendMessage(message, message.getAllRecipients());

                    log.info("带附件邮件成功发送至: {}，附件数量: {}", recipient, attachments.size());
                    successCount++;

                    // 添加短暂延迟，避免发送频率过高触发服务器限制
                    // Thread.sleep(1000); // 可根据需要取消注释

                } catch (Exception e) {
                    log.error("发送带附件邮件到 {} 时失败: {}", recipient, e.getMessage());
                    failureCount++;
                    // 继续发送后续邮件，不因单个失败而中断整个批量任务
                }
            }

            log.info("带附件邮件发送完成: 成功 {} 封, 失败 {} 封，总附件数: {}", successCount, failureCount, attachments.size());

        } catch (Exception e) {
            log.error("带附件邮件发送过程中发生异常: {}", e.getMessage());
            return false;
        } finally {
            // 确保关闭连接
            if (transport != null && transport.isConnected()) {
                try {
                    transport.close();
                    log.info("SMTP连接已关闭");
                } catch (Exception e) {
                    log.warn("关闭SMTP连接时出错: {}", e.getMessage());
                }
            }

            // 更新发送记录
            try {
                if (successCount > 0) {
                    emailSendRecordMapper.successEmailSend(customEmailSendDTO.getSendEmailId(), successCount);
                } else {
                    emailSendRecordMapper.failEmailSend(customEmailSendDTO.getSendEmailId());
                }
            } catch (Exception e) {
                log.warn("更新邮件发送记录时出错: {}", e.getMessage());
            }
        }

        return successCount > 0; // 只要成功发送至少一封就返回true
    }

    /**
     * 邮箱服务器配置类
     */
    private static class EmailServerConfig {
        private final String host;
        private final int port;
        private final boolean startTlsEnable;

        public EmailServerConfig(String host, int port, boolean startTlsEnable) {
            this.host = host;
            this.port = port;
            this.startTlsEnable = startTlsEnable;
        }

        public String getHost() {
            return host;
        }

        public int getPort() {
            return port;
        }

        public boolean isStartTlsEnable() {
            return startTlsEnable;
        }
    }

    /**
     * 附件数据类
     */
    private static class AttachmentData {
        private final String filename;
        private final byte[] data;

        public AttachmentData(String filename, byte[] data) {
            this.filename = filename;
            this.data = data;
        }

        public String getFilename() {
            return filename;
        }

        public byte[] getData() {
            return data;
        }
    }
} 